package com.rainflowerstone.service;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.text.format.Formatter;
import android.util.Log;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.model.Progress;
import com.lzy.okgo.request.base.Request;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
import com.rainflowerstone.R;
import com.rainflowerstone.utils.CountDownUtils;
import com.rainflowerstone.utils.Urls;

import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Set;
import okhttp3.Headers;
import retrofit2.Retrofit;

/**
 * Created by zs on 2016/7/8.
 */
public class DownLoadService extends Service {

    private int NOTIFY_ID = 1000;

    private static final String NOTIFY_CHANNEL_ID = "OK_CHANNEL_ID";

    private static final String NOTIFY_CHANNEL_NAME = "OK_CHANNEL_NAME";

    private NotificationManager manager;

    private QMUITipDialog mQMUITipDialog;

    private Boolean isUpdate=false;

    /**
     * 目标文件存储的文件名
     */
    private Context mContext;
    private Retrofit.Builder retrofit;
    private CountDownUtils mCountDownUtils;


    //自定义静态方法用于调用服务
    public static void startService(Context context,String downloadUrl) {
        Intent intent = new Intent(context, DownLoadService.class);
        intent.putExtra("url", downloadUrl);
        context.startService(intent);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        mContext = this;
        initTimeCount();
        loadFile();
        return super.onStartCommand(intent, flags, startId);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

//    public class Binder extends android.os.Binder{//此方法用于向service传值
//        public void setData(Context context){
//            DownLoadService.this.context=context;
//        }
//    }

    /**
     * 下载文件
     */
    private void loadFile() {
        if (retrofit == null) {
            retrofit = new Retrofit.Builder();
        }
        if(isUpdate){
            //提示信息显示三秒(可以自定义)
//            mCountDownUtils.start();
//            mQMUITipDialog=new QMUITipDialog.Builder(mContext)
//                    .setIconType(QMUITipDialog.Builder.ICON_TYPE_INFO)
//                    .setTipWord("正在请求，请稍后...")
//                    .create();
//            mQMUITipDialog.show();
            return;
        }
        isUpdate=true;
        //此处做下载处===========================================================
        OkGo.<File>get(Urls.URL_DOWNLOAD)
                .tag(this)
                .headers("header1", "headerValue1")//
                .params("param1", "paramValue1")//
                .execute(new com.lzy.okgo.callback.FileCallback("RainFlowerStone2.0-v1.0.apk") {
                    @Override
                    public void onStart(Request<File, ? extends Request> request) {
                        showProgressNotification("下载", "正在链接资源...", 0, true);
                    }

                    @Override
                    public void onSuccess(com.lzy.okgo.model.Response<File> response) {

                        //提示信息显示三秒(可以自定义)
                        mCountDownUtils.start();
                        mQMUITipDialog=new QMUITipDialog.Builder(mContext)
                                .setIconType(QMUITipDialog.Builder.ICON_TYPE_INFO)
                                .setTipWord("下载完成")
                                .create();
                        mQMUITipDialog.show();
                        //取消指定ID 的通知
                        manager.cancel(NOTIFY_ID);
                        File file = response.body();
                        Log.e("update", "onSuccess: 下载完成" + "安装包名称" + file.getName());
                        Log.e("update", "onSuccess: 下载完成" + "安装包路劲" + file.getPath());
//                        installApk(file);
                        handleResponse(response);
                    }

                    @Override
                    public void onError(com.lzy.okgo.model.Response<File> response) {
                        isUpdate=false;
                        //提示信息显示三秒(可以自定义)
//                        mCountDownUtils.start();
//                        mQMUITipDialog=new QMUITipDialog.Builder(mContext)
//                                .setIconType(QMUITipDialog.Builder.ICON_TYPE_INFO)
//                                .setTipWord("下载出错")
//                                .create();
//                        mQMUITipDialog.show();
                        //取消该应用程序发送的所有通知
                        //manager.cancelAll();
                        //取消指定ID 的通知
                        manager.cancel(NOTIFY_ID);
                        handleError(response);
                    }

                    @Override
                    public void downloadProgress(Progress progress) {
                        Log.e("update", "downloadProgress: " + progress.fraction);
                        //当前下载长度
                        String downloadLength = Formatter.formatFileSize(getApplicationContext(), progress.currentSize);
                        //总长度
                        String totalLength = Formatter.formatFileSize(getApplicationContext(), progress.totalSize);
                        showProgressNotification("RainFlowerStone2.0-v"+1.0+".apk", "已下载" +  Math.round(progress.fraction*100)+ "%",  Math.round(progress.fraction*100), false);
                    }
                });
    }

    /**
     * 带有进度条的通知
     *
     * @param fileName      通知标题
     * @param info          通知内容
     * @param progress      当前进度
     * @param indeterminate 是否是不明确的
     */

    private void showProgressNotification(String fileName, String info, int progress, boolean indeterminate) {
        //Step1:获取通知管理器
        manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
        //在Android(O) 8.0 及以上,需要做以下配置
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            if (manager != null) {
                NotificationChannel notificationChannel = new NotificationChannel(NOTIFY_CHANNEL_ID, NOTIFY_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
                manager.createNotificationChannel(notificationChannel);
            }
        }
        //NotificationManagerCompat manager = NotificationManagerCompat.from(this);
        if (manager != null) {
            //Step3: 构造 Notification 对象
            Notification notification = new NotificationCompat.Builder(this, NOTIFY_CHANNEL_ID)
                    //设置通知的 小图标(必须设置,否则通知不显示)
                    .setSmallIcon(R.mipmap.about_logo)
                    //通知标题
                    .setContentTitle(fileName)
                    //参数1是:总进度,参数2是:当前进度,参数3是:是否不明确
                    .setProgress(100, progress, indeterminate)
                    //设置 通知 显示的时间
                    .setWhen(System.currentTimeMillis() - 3600000L)
                    //通知的内容
                    .setContentText(info)
                    //设置 通知 来时的触发(铃声\震动\闪光)
                    .setDefaults(Notification.DEFAULT_ALL)
                    //构造Notification对象
                    .build();

//            notification.flags |= Notification.FLAG_NO_CLEAR; //让通知不能滑动取消
//            notification.flags |= Notification.FLAG_INSISTENT; //重复发出 通知的声音/震动 直到用户点击该通知
//            notification.flags |= Notification.FLAG_ONGOING_EVENT; //让通知 显示 正在运行
            notification.flags |= Notification.FLAG_AUTO_CANCEL; //让通知被点击之后自动取消掉
            //Step2:唤醒通知, 每个 通知的ID 是唯一的.如果ID一样,则通知栏不会创建新的通知,会重用原来的通知
            manager.notify(NOTIFY_ID, notification);
        }
    }


    private  <T> void handleResponse(com.lzy.okgo.model.Response<T> response) {

        StringBuilder sb;
        okhttp3.Call call = response.getRawCall();
        if (call != null) {
            Headers requestHeadersString = call.request().headers();
            Set<String> requestNames = requestHeadersString.names();
            sb = new StringBuilder();
            for (String name : requestNames) {
                sb.append(name).append(" ： ").append(requestHeadersString.get(name)).append("\n");
            }
        } else {
        }
        T body = response.body();
        if (body == null) {
        } else {
            if (body instanceof String) {
            } else if (body instanceof List) {
                sb = new StringBuilder();
                List list = (List) body;
                for (Object obj : list) {
                    sb.append(obj.toString()).append("\n");
                }
            } else if (body instanceof Set) {
                sb = new StringBuilder();
                Set set = (Set) body;
                for (Object obj : set) {
                    sb.append(obj.toString()).append("\n");
                }
            } else if (body instanceof Map) {
                sb = new StringBuilder();
                Map map = (Map) body;
                Set keySet = map.keySet();
                for (Object key : keySet) {
                    sb.append(key.toString()).append(" ： ").append(map.get(key)).append("\n");
                }
            } else if (body instanceof File) {
                File file = (File) body;
            } else if (body instanceof Bitmap) {
            } else {
            }
        }
    }

    private  <T> void handleError(com.lzy.okgo.model.Response<T> response) {
        if (response == null) return;
        if (response.getException() != null) response.getException().printStackTrace();
        StringBuilder sb;
        okhttp3.Call call = response.getRawCall();
        if (call != null) {
//            requestState.setText("请求失败  请求方式：" + call.request().method() + "\n" + "url：" + call.request().url());
            System.out.println("请求失败 请求方式"+call.request().method()+"\n" + "url：" + call.request().url());
            Headers requestHeadersString = call.request().headers();
            Set<String> requestNames = requestHeadersString.names();
            sb = new StringBuilder();
            for (String name : requestNames) {
                sb.append(name).append(" ： ").append(requestHeadersString.get(name)).append("\n");
            }
        } else {
        }

        okhttp3.Response rawResponse = response.getRawResponse();
        if (rawResponse != null) {
            Headers responseHeadersString = rawResponse.headers();
            Set<String> names = responseHeadersString.names();
            sb = new StringBuilder();
            sb.append("stateCode ： ").append(rawResponse.code()).append("\n");
            for (String name : names) {
                sb.append(name).append(" ： ").append(responseHeadersString.get(name)).append("\n");
            }
        } else {
        }
    }

    private void initTimeCount(){
        // 开始启动计时器
        mCountDownUtils = CountDownUtils.getCountDownTimer()
                .setMillisInFuture(2000)
                .setCountDownInterval(1000)
                .setTickDelegate(pMillisUntilFinished -> {//倒计时发生事件

                })
                .setFinishDelegate(() -> {//倒计时结束
                    mQMUITipDialog.dismiss();
                });
    }

    /**
     * 安装软件
     * @param file
     */
    private void installApk(File file) {
        Uri uri = Uri.fromFile(file);
        Intent install = new Intent(Intent.ACTION_VIEW);
        install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        install.setDataAndType(uri, "application/vnd.android.package-archive");
        // 执行意图进行安装
        mContext.startActivity(install);
    }
}
